﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Xml;

using Kiosk.Utilities;
using System.Configuration;
using System.Threading;
using System.Windows.Threading;
using System.Windows.Media.Animation;
using Microsoft.Samples.KMoore.WPFSamples.Transition;
using Kiosk.UserControls;
using System.ComponentModel;

namespace Kiosk.Frontend
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class frmMain : Window
    {
        private object rssLock = new Object();
        public DispatcherTimer timer;
        public RssReaderCollection readers;
        public DateTime lastRssChange,
                        lastRssRefresh = DateTime.Now,
                        lastNotificationRefresh = DateTime.Now,
                        lastWeatherUpdate = DateTime.Now;
        public DateTime lastMovement = DateTime.Now;
        public string keyboardInput = "";
        public HomeScreen homeScreen;
        public EmployeeDirectoryScreen directoryScreen;
        public HelpScreen helpScreen;

        #region Constructor and Load
        public frmMain()
        {
            InitializeComponent();
            homeScreen = new HomeScreen();
            homeScreen.NavigateEvent += new NavigateEventHandler(changeScreens_Event);
            homeScreen.Height = Double.NaN;
            homeScreen.Width = Double.NaN;
            helpScreen = new HelpScreen();
            helpScreen.NavigateEvent += new NavigateEventHandler(changeScreens_Event);
            helpScreen.Width = double.NaN;
            helpScreen.Height = double.NaN;
            directoryScreen = new EmployeeDirectoryScreen();
            directoryScreen.NavigateEvent += new NavigateEventHandler(changeScreens_Event);
            directoryScreen.Height = double.NaN;
            directoryScreen.Width = double.NaN;
            transUCPresenter.Content = homeScreen;

        }

        private void frmMain_Loaded(object sender, RoutedEventArgs e)
        {
            mediaPlayer.Source = new Uri("media/pirates.mp3", UriKind.Relative);
 
            UpdateInfoDisplays();
            UpdateWeather(true);

            InitRSS();
            lastMovement = DateTime.Now;

            // run the timer event every 5 second
            timer = new DispatcherTimer();
            timer.Interval = TimeSpan.FromSeconds(1);
            timer.Tick += new EventHandler(timer_Tick);
            timer.Start();
        }
        #endregion

        private void UpdateInfoDisplays()
        {
            txtMonth.Text = DateTime.Now.ToString("MMMM");
            txtDay.Text = DateTime.Now.Day.ToString();
            txtTime.Text = DateTime.Now.ToShortTimeString();
        }


        void changeScreens_Event(object sender, NavigateEventArgs e)
        {

            if (transUCPresenter.Content is HomeScreen)
            {
                homeScreen.PausePresentation();
            }
            else if (e.NewScreen is HomeScreen)
            {
                homeScreen.ShowPresentation();
            }
            transUCPresenter.Content = e.NewScreen;
        }

        #region Timer Events/Methods
        void timer_Tick(object sender, EventArgs e)
        {
            keyboardInput = "";
            UpdateWeather(false);

            UpdateInfoDisplays();

            ChangeRSS();

            RefreshRssFeeds();

            BackToHomeScreen();

            RefreshNotifications();
        }

        private void RefreshNotifications()
        {
            if (lastNotificationRefresh < DateTime.Now.AddSeconds(-15))
            {
                if (transUCPresenter.Content is HomeScreen)
                {
                    ((HomeScreen)transUCPresenter.Content).RefreshNotifications();
                }
            }
        }

        private void BackToHomeScreen()
        {
            // if we are sitting on the home screen just return
            if ((transUCPresenter.Content is HomeScreen) && ((HomeScreen)transUCPresenter.Content).ShowingPresentation)
            {
                return;
            }

            if (lastMovement < DateTime.Now.AddSeconds(-60) && lastMovement >= DateTime.Now.AddSeconds(-70))
            {
                DisplayInactivityWarning();
            }
            else if (lastMovement < DateTime.Now.AddSeconds(-70))
            {
                if (transUCPresenter.Content is HomeScreen)
                {
                    ((HomeScreen)transUCPresenter.Content).ShowPresentation();
                }
                else
                {
                    NavigateEventArgs args = new NavigateEventArgs(homeScreen);
                    changeScreens_Event(this, args);
                }
                HideInactivityWarning();
            }
        }

        bool warningDisplayed = false;
        private void HideInactivityWarning()
        {
            if (warningDisplayed)
            {
                warningDisplayed = false;
                brdWarning.Opacity = 0;
                brdWarning.IsHitTestVisible = false;
                DoubleAnimation da = new DoubleAnimation(0, new Duration(TimeSpan.FromSeconds(.25)));
                brdWarning.BeginAnimation(Border.OpacityProperty, da);
            }
        }

        private void DisplayInactivityWarning()
        {
            if (!warningDisplayed)
            {
                warningDisplayed = true;
                brdWarning.Opacity = 1;
                brdWarning.IsHitTestVisible = true;
                DoubleAnimation da = new DoubleAnimation(1, new Duration(TimeSpan.FromSeconds(.5)));
                brdWarning.BeginAnimation(Border.OpacityProperty, da);
            }
        }

        private void RefreshRssFeeds()
        {
            if (lastRssRefresh < DateTime.Now.AddHours(-1))
            {
                lock (rssLock)
                {
                    readers.RefreshAll();
                    lastRssRefresh = DateTime.Now;
                }
            }
        }

        private void ChangeRSS()
        {
            if (lastRssChange < DateTime.Now.AddSeconds(-30))
            {
                transPresenter.Content = readers.GetNextEntry();
                lastRssChange = DateTime.Now;
            }
        }
        #endregion

        #region RSS Methods
        private void InitRSS()
        {
            BackgroundWorker rssBw = new BackgroundWorker();
            rssBw.DoWork += new DoWorkEventHandler(rssBw_DoWork);
            rssBw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(rssBw_RunWorkerCompleted);
            rssBw.RunWorkerAsync();
        }

        void rssBw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            ChangeRSS();
            transPresenter.Content = readers.CurrentEntry;
            lastRssRefresh = DateTime.Now;
        }

        void rssBw_DoWork(object sender, DoWorkEventArgs e)
        {
            RssConfigSection section = (RssConfigSection)ConfigurationManager.GetSection("RssConfig");
            lock (rssLock)
            {
                readers = new RssReaderCollection();
                foreach (FeedElement f in section.FeedItems)
                {
                    readers.Add(new RssReader(f));
                }
            }
        }


	    #endregion

        private void Window_MouseMove(object sender, MouseEventArgs e)
        {
            lastMovement = DateTime.Now;
            HideInactivityWarning();
        }

        #region Image Button Events
        private void DirectoryImage_MouseUp(object sender, MouseButtonEventArgs e)
        {
            if (!(transUCPresenter.Content is EmployeeDirectoryScreen))
            {
                NavigateEventArgs args = new NavigateEventArgs(directoryScreen);
                changeScreens_Event(sender, args);
            }
        }

        private void HomeImage_MouseUp(object sender, MouseButtonEventArgs e)
        {
            if (!(transUCPresenter.Content is HomeScreen))
            {
                NavigateEventArgs args = new NavigateEventArgs(homeScreen);
                changeScreens_Event(sender, args);
            }
        }

        private void HelpImage_MouseUp(object sender, MouseButtonEventArgs e)
        {
            if (!(transUCPresenter.Content is HelpScreen))
            {
                NavigateEventArgs args = new NavigateEventArgs(helpScreen);
                changeScreens_Event(sender, args);
            }
        }

        #endregion

        #region Easter Egg Code
		
        private void Window_KeyUp(object sender, KeyEventArgs e)
        {
            ProcessKeyboardInput(e.Key);

        }

        private void ProcessKeyboardInput(Key key)
        {
            if (key == Key.F11 && this.WindowStyle != WindowStyle.None)
            {
                this.WindowStyle = WindowStyle.None;
                this.WindowState = WindowState.Maximized;
            }
            else if (key == Key.F11)
            {
                this.WindowStyle = WindowStyle.SingleBorderWindow;
                this.WindowState = WindowState.Normal;
            }
            else
            {
                keyboardInput += key.ToString().ToLower();
                if (keyboardInput == "epic")
                {
                    keyboardInput = "";
                    mediaPlayer.Play();
                }
                if (keyboardInput == "lame")
                {
                    keyboardInput = "";
                    mediaPlayer.Stop();

                }
            }
        }

        void mediaPlayer_MediaFailed(object sender, ExceptionRoutedEventArgs e)
        {
            
        }

        private void Window_MouseUp(object sender, MouseButtonEventArgs e)
        {
            switch(e.ChangedButton)
            {
                case MouseButton.Left:
                    keyboardInput = "e";
                    break;
                case MouseButton.Middle:
                    if (keyboardInput == "epi")
                    {
                        ProcessKeyboardInput(Key.C);
                    }
                    break;
                case MouseButton.Right:
                    if (keyboardInput == "e")
                    {
                        keyboardInput += "p";
                    }
                    else if (keyboardInput == "ep")
                    {
                        keyboardInput += "i";
                    }
                    break;
            }


            

        }

        private void Window_MouseDown(object sender, MouseButtonEventArgs e)
        {
            if (e.LeftButton == MouseButtonState.Pressed
                && e.MiddleButton == MouseButtonState.Pressed
                && e.RightButton == MouseButtonState.Pressed)
            {
                keyboardInput = "lam";
                ProcessKeyboardInput(Key.E);
            }
        }

	    #endregion

        #region Weather Code
        private void UpdateWeather(bool forceUpdate)
        {
            if (lastWeatherUpdate > DateTime.Now.AddMinutes(-15) || forceUpdate)
            {
                BackgroundWorker weatherBw = new BackgroundWorker();
                weatherBw.DoWork += new DoWorkEventHandler(weatherBw_DoWork);
                weatherBw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(weatherBw_RunWorkerCompleted);
                weatherBw.RunWorkerAsync();
            }
        }

        void weatherBw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            string[] tempWeather = (string[])e.Result;
            txtTemp.Text = tempWeather[0] + "°";
            Uri u = new Uri(tempWeather[1] ,UriKind.Relative);
            BitmapImage bi = new BitmapImage(u);
            imgWeather.Source = bi;


        }

        void weatherBw_DoWork(object sender, DoWorkEventArgs e)
        {
            string path = "images/weather/";
            string[] tempWeather = new string[2];

            try
            {
                string weatherFeed = ConfigurationManager.AppSettings["WeatherFeed"];
                XmlDocument xmlDoc = new XmlDocument();

                // Load the weather data from the XML feed.
                xmlDoc.Load(weatherFeed);

                // Retrieve current temperature
                string temp = xmlDoc.SelectSingleNode("//temp_f").InnerText;

                // Retrieve current conditions icon name
                string iconName = xmlDoc.SelectSingleNode("//icon_url_name").InnerText;

                iconName = iconName.Replace("jpg", "png");
                string icon = path + iconName;

                tempWeather[0] = temp;
                tempWeather[1] = icon;

                

            }
            catch (Exception ex)
            {
                tempWeather[0] = "N/A";
                tempWeather[1] = path + "NA.png";
            }
            finally
            {
                lastWeatherUpdate = DateTime.Now;

                e.Result = tempWeather;

            }
        }
        #endregion

        private void rssMouseUP(object sender, MouseButtonEventArgs e)
        {
            NavigateEventArgs args = new NavigateEventArgs(new RssScreen() { Width = double.NaN, Height = double.NaN, DataContext=transPresenter.Content });
            changeScreens_Event(sender, args);
        }
    }
}
